import mqtt from 'precompiled-mqtt';
import type { MqttClient } from 'precompiled-mqtt';
import { notification } from 'ant-design-vue';
// 连接选项
const options = {
  clean: true, // true: 清除会话, false: 保留会话
  connectTimeout: 4000, // 超时时间
  // 认证信息
  clientId: 'camellia-web' + Date.now(),
  //username: 'camellia-web',
  // password: 'emqx_test',
};

// 连接字符串, 通过协议指定使用的连接方式
// ws 未加密 WebSocket 连接
// wss 加密 WebSocket 连接
// mqtt 未加密 TCP 连接
// mqtts 加密 TCP 连接
// wxs 微信小程序连接
// alis 支付宝小程序连接
const maxRetryCount = 10;
let retryCount = 0;

const connectUrl = 'ws://123.60.15.219:8083/mqtt';
let client: MqttClient;
const listeners = new Map();

export function connectMqtt(): MqttClient {
  if (client != null && client.connected) {
    showConnectSuccess();
    return client;
  }
  console.log('mqtt 连接地址：{}', connectUrl);
  client = mqtt.connect(connectUrl, options);
  client.on('reconnect', (error) => {
    console.log('正在重连:', error);
  });

  client.on('connect', function () {
    console.log('连接成功');
    showConnectSuccess();
  });

  client.on('error', (error) => {
    console.log('连接失败:', error);
    showConnectError();
  });

  client.on('message', (topic, message) => {
    console.log('收到消息：', topic, message.toString());
    for (const callback of listeners.keys()) {
      try {
        callback(topic, message.toString());
      } catch (err) {
        console.error(err);
      }
    }
  });
  return client;
}

export function closeMqtt() {
  if (client && client.connected) {
    client.end(true);
  }
}

export function publish(topic, message) {
  client.publish(topic, message);
  console.log('发送消息：', topic, message.toString());
  notification.success({
    message: 'MQTT服务',
    description: `MQTT消息发送成功，Topic: ${topic}`,
    duration: 5,
  });
}

/**
 * 添加 WebSocket 消息监听
 * @param callback
 */
export function onMQTTMessageRegister(callback: (topic: string, message: string) => any) {
  if (!listeners.has(callback)) {
    if (typeof callback === 'function') {
      listeners.set(callback, null);
    } else {
      console.debug('[MQTTT] 添加 MQTT 消息监听失败：传入的参数不是一个方法');
    }
  }
}

export function subscribe(topic) {
  if (client && client.connected) {
    client.subscribe(topic, { qos: 0 }, function (error) {
      if (error) {
        showSubscribeError(topic);
        console.log(`${topic} 订阅失败${error}`);
      } else {
        retryCount = 0;
        console.log(`${topic} 订阅成功`);
        showSubscribeSuccess(topic);
      }
    });
  } else {
    retryCount = retryCount + 1;
    if (retryCount > maxRetryCount) {
      return;
    }
    setTimeout(() => {
      subscribe(topic);
    }, 500);
  }
}

export function unSubscribe(topic) {
  if (client && client.connected) {
    client.unsubscribe(topic);
  }
}

function showConnectSuccess() {
  // notification.success({
  //   message: 'MQTT服务连接成功',
  //   description: `MQTT服务连接成功，服务地址: ${connectUrl}`,
  //   duration: 3,
  // });
}
function showConnectError() {
  notification.error({
    message: 'MQTT服务连接失败',
    description: `MQTT服务连接失败，服务地址: ${connectUrl}`,
    duration: 3,
  });
}

function showSubscribeError(topic) {
  notification.error({
    message: 'MQTT服务订阅',
    description: `MQTT服务订阅失败，Topic: ${topic}`,
    duration: 5,
  });
}

function showSubscribeSuccess(topic) {
  // notification.success({
  //   message: 'MQTT服务订阅',
  //   description: `MQTT服务订阅成功，Topic: ${topic}`,
  //   duration: 5,
  // });
}
